package com.act.task;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.act.util.CarbonJdbcUtils;
import com.act.util.CommonUtils;
import com.act.util.JdbcUtil;
import com.act.util.SystemConfig;
import com.act.util.URLUtil;

public class DomainJdbcTask {

	private static final Log log = LogFactory.getLog(DomainJdbcTask.class);
	
	public static void main(String[] args){
		PreparedStatement ps = null;
		ResultSet rs = null;
		Connection conn = null;
		try{
			String dayStr = "";
			if(args.length > 0){
				//时间格式:20171026
				dayStr = args[0];
			}
			log.info("传入的时间："+dayStr);
			
			String carbonDB = SystemConfig.getProperty("carbonDB");
			String tableName = carbonDB+".t_detector_check_fraud_"+getExecDate(dayStr);
			log.info("insert tableName："+tableName);
			
			conn = CarbonJdbcUtils.getConnection();
			ps = conn.prepareStatement("select type,isfraud,fraudtype,subfraudtype,country,province,area,host,url,urlparam,ip,state,control,isforeign,isweb,operator,md5,appname,sitetype,sitetypename,checkmonth,checkdate,checkhour,checktime,time,logtime,uuid,modifytime from "+tableName+" where type= '0'");
			rs = ps.executeQuery();
			
			List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
			int n = 0;
			while(rs.next()){
				String host = rs.getString("host");;
				try{
					String topDomain = URLUtil.getDomainName("http://" + host);
					if(StringUtils.isNotBlank(topDomain)){
						Map<String,Object> map = new HashMap<String,Object>();
						map.put("id", 0);
						map.put("type", rs.getString("type"));
						map.put("isfraud", rs.getString("isfraud"));
						map.put("fraudtype", rs.getString("fraudtype"));
						map.put("subfraudtype",rs.getString("subfraudtype"));
						map.put("country", rs.getString("country"));
						map.put("province", rs.getString("province"));
						map.put("area",rs.getString("area"));
						map.put("host",host);
						map.put("url", rs.getString("url"));
						map.put("urlparam", rs.getString("urlparam"));
						map.put("ip", rs.getString("ip"));
						map.put("state", rs.getString("state"));
						map.put("control", rs.getString("control"));
						map.put("isforeign", rs.getString("isforeign"));
						map.put("isweb", rs.getString("isweb"));
						map.put("operator", rs.getString("operator"));
						map.put("md5", rs.getString("md5"));
						map.put("appname", rs.getString("appname"));
						map.put("sitetype", rs.getString("sitetype"));
						map.put("sitetypename", rs.getString("sitetypename"));
						map.put("checkmonth", rs.getString("checkmonth"));
						map.put("checkdate", rs.getString("checkdate"));
						map.put("checkhour", rs.getString("checkhour"));
						map.put("checktime",rs.getObject("checktime"));
						map.put("time", rs.getObject("time"));
						map.put("logtime", rs.getObject("logtime"));
						map.put("uuid",rs.getObject("uuid"));
						map.put("modifytime", rs.getString("modifytime"));
						map.put("checkdate", rs.getString("checkdate"));
						map.put("isdail", "");
						map.put("isdomain","");
						map.put("location", "");
						map.put("topdomain",topDomain);
						list.add(map);
						if (++n % 100000 == 0) {
							log.info("当前解析的条数:"+n);
						}
					}
				}catch(Exception e){
					log.info("当前解析出错的域名为："+host);
					if(log.isErrorEnabled()){
						log.error(e.getMessage(),e);
					}
				}
			}
			log.info("数据量："+list.size());
			log.info("===========开始数据插入=======");
			insertData(list);
			log.info("===========数据插入完成=======");
			//各专题汇总
			StatisticsTask.statics();
			
		}catch(Exception e){
			if(log.isErrorEnabled()){
				log.error(e.getMessage(),e);
			}
		}finally{
			CarbonJdbcUtils.close(rs, ps, conn);
		}
	}
	
	private static void insertData(List<Map<String,Object>> list) {
		if(list.size() > 0){
			PreparedStatement ps = null;
			Connection conn = null;
			try{
				String columns = "id,type,country,province,area,host,url,urlparam,ip,state,control,isforeign,isweb,operator,md5,appname,sitetype,sitetypename,checkmonth,checkdate,checkhour,checktime,time,logtime,uuid,modifytime,isdail,isdomain,location,isfraud,fraudtype,subfraudtype,topdomain";
				String[] columnsSplit = columns.split(",");
				conn = JdbcUtil.getConnection();
				
				createSeqIfNotExists(conn);
				String sql = "truncate table ods_idc_t_detector_check_fraud";
				
				boolean flag = execSql(conn,sql);
				if(flag){
					sql = "insert into ods_idc_t_detector_check_fraud("+columns+") values(CHECK_FRAUD_SE.nextval,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
					conn.setAutoCommit(false);
					ps = conn.prepareStatement(sql);
					int n = 0;
					for(Map<String,Object> map : list){
						for (int i = 0; i < map.size()-1; i++) {
							ps.setObject(i+1, map.get(columnsSplit[i+1]));
						}
						ps.addBatch();
						if (++n % 5000 == 0) {
							ps.executeBatch();
							log.info("当前插入的条数:"+n);
							conn.commit();
						}
					}
					ps.executeBatch();
					conn.commit();
				}
			}catch(Exception e){
				if(log.isErrorEnabled()){
					log.error(e.getMessage(),e);
				}
			}finally{
				JdbcUtil.close(ps, conn);
			}
		}
	}
	
	public static String getExecDate(String dayStr) {
		if (StringUtils.isBlank(dayStr)) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
			dayStr = sdf.format(new Date());
		}
		return dayStr;
	}
	
	public static void createSeqIfNotExists(Connection conn){
		try{
			String sequenceName = "CHECK_FRAUD_SE";
			CommonUtils.getSequenceName(sequenceName,conn);
		}catch(Exception e){
			if(log.isErrorEnabled()){
				log.error(e.getMessage(),e);
			}
		}
	}
	
	private static boolean execSql(Connection conn,String sql){
    	boolean flag = true;
    	PreparedStatement ps = null;
    	try{
    		conn.setAutoCommit(false);
    		ps = conn.prepareStatement(sql);
          	ps.executeQuery();
            conn.commit();
          	flag = true;
          }
          catch(SQLException e){
         	 flag = false;
         	 log.error("jdbc batch commit sql:"+sql+" error" , e);
              try {
                  conn.rollback();
              } catch (SQLException e1) {
                  log.error("jdbc rollback error" , e1);
              }
          }finally{
        	  JdbcUtil.close(ps);
          }
    	return flag ;
    }
}
